package com.manong.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.manong.config.security.Utils;
import com.manong.dao.AttendanceManagementDao;
import com.manong.dao.UserMapper;
import com.manong.entity.AttendanceManagement;
import com.manong.entity.Department;
import com.manong.entity.SysSalary;
import com.manong.entity.User;
import com.manong.service.AttendanceManagementService;
import com.manong.vo.AttendanceManagementVo;
import com.manong.vo.CommonReqVo;
import com.manong.vo.SysSalaryVo;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * (AttendanceManagement)表服务实现类
 *
 * @author makejava
 * @since 2024-05-18 10:28:45
 */
@Service("attendanceManagementService")
@RequiredArgsConstructor
public class AttendanceManagementServiceImpl extends ServiceImpl<AttendanceManagementDao, AttendanceManagement> implements AttendanceManagementService {

    private final UserMapper userMapper;
    @Override
    public Boolean save1(AttendanceManagement attendanceManagement) {

        // 判断字段不能为空
        if (attendanceManagement.getClassStartTime() == null) {
            throw new RuntimeException(" 上班时间不能为空 ");
        }
        if (attendanceManagement.getClassEndTime() == null) {
            throw new RuntimeException(" 下班时间不能为空 ");
        }

        String status = "正常出勤";

        // 如果 上班时间 在早上八点之后，就是迟到
        if (attendanceManagement.getClassStartTime().isAfter(LocalTime.of(8, 0, 0))) {
            status = "迟到";
        }
        // 如果下班时间 在18点之前就是早退
        if (attendanceManagement.getClassEndTime().isBefore(LocalTime.of(18, 0, 0))) {
            status = status + " 早退";
        }
        attendanceManagement.setAttendanceStatus(status);
        // 插入或者更新
        this.saveOrUpdate(attendanceManagement);
        return true;
    }

    @Override
    public Boolean delete1(CommonReqVo commonReqVo) {
        return this.removeBatchByIds(commonReqVo.getMainIds());
    }

    @Override
    public IPage listAll(CommonReqVo commonReqVo) {
        User user = Utils.getUser();
        Integer isAdmin = user.getIsAdmin();
        val userId = user.getId();
        //分页查询必备，填充分页参数
        IPage<AttendanceManagement> page = new Page<AttendanceManagement>(commonReqVo.getPageNo(),
                commonReqVo.getPageSize());
        //条件构造器，便于 为查询添加查询条件的
        LambdaQueryWrapper<AttendanceManagement> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        //如果 commonReqVo.getUserIds() 集合为空，就不添加 根据用户id 的查询条件，否则 就会 添加查询条件（更加用户id）  ，
        //会添加  user_id in ( 1,3,6)
        lambdaQueryWrapper.in(Objects.equals(1, isAdmin) && !CollectionUtils.isEmpty(commonReqVo.getUserIds()), AttendanceManagement::getUserId, commonReqVo.getUserIds());
        // 如果不是超级管理员 只能查看自己的信息
        lambdaQueryWrapper.eq(!Objects.equals(1, isAdmin),AttendanceManagement::getUserId,userId);
         //分页查询
        final IPage<AttendanceManagement> page1 = this.page(page, lambdaQueryWrapper);

        // 这是查询所有用户数据，因为 SysSalary 中不存储 用户名， 是根据用户id 进行外键关联的，所以返回给前端的时候需要把用户名称也返回给前端
        final List<User> users = userMapper.selectList(new QueryWrapper<>());

        // 拿到 分页查询结果中的数据集合
        final List<AttendanceManagement> records = page1.getRecords();
        System.out.println(page1.getTotal());
        IPage<AttendanceManagementVo> attendanceManagementVoIPage = new Page<>();
        // 这是 拷贝属性，因为 IPage<SysSalary> 中 只有部门id字段，没有部门名称字段，
        // 而返回给前端的时候需要部门名称，所以新创建一个对象，包含部门名称
        //也没有用户名称字段， 也需要返回用户名称字段给前端
        BeanUtils.copyProperties(page1, attendanceManagementVoIPage);
        List<AttendanceManagementVo> attendanceManagementVos = new ArrayList<>();
        //这里是 for循环每个分页结果中的数据对象，填充 部门名称字段
        for (AttendanceManagement record : records) {

            AttendanceManagementVo one = new AttendanceManagementVo();
            BeanUtils.copyProperties(record, one);

            final Long userId1 = record.getUserId();
            //stream 是jdk8自带的方便操作集合的流，eg，对list元素进行分组，聚合，求最大值，最小值，等等，几行代码就可以完成通过for循环传统操作几十行代码完成的功能
            // 匹配用户
            final Optional<User> first1 = users.stream()
                    .filter(u -> Objects.equals(u.getId(), userId1))
                    .findFirst();
            //如果 系统中不存在指定用户id的数据，就不填充用户名称，否则就填充（正常情况下会有的）
            if (first1.isPresent()) {
                final String username = first1.get().getUsername();
                one.setUserName(username);
            }

            attendanceManagementVos.add(one);
        }
        //把填充好部门名称的数据塞到返回体里面，然后返回给前端
        attendanceManagementVoIPage.setRecords(attendanceManagementVos);
        return attendanceManagementVoIPage;
    }

}
